package com.share.order.service.impl;

import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.share.common.core.domain.Result;
import com.share.common.core.exception.ServiceException;
import com.share.common.core.utils.bean.BeanUtils;
import com.share.common.security.utils.SecurityUtils;
import com.share.order.domain.*;
import com.share.order.mapper.OrderBillMapper;
import com.share.order.mapper.OrderInfoMapper;
import com.share.order.service.IOrderInfoService;
import com.share.rules.api.RemoteFeeRuleService;
import com.share.rules.domain.FeeRule;
import com.share.rules.domain.FeeRuleRequestForm;
import com.share.rules.domain.FeeRuleResponseVo;
import com.share.user.api.RemoteH5UserService;
import com.share.user.domain.UserInfo;
import org.joda.time.DateTime;
import org.joda.time.Minutes;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Arrays;
import java.util.Date;

@Service
public class OrderInfoServiceImpl extends ServiceImpl<OrderInfoMapper, OrderInfo> implements IOrderInfoService {

    @Autowired
    private OrderInfoMapper orderInfoMapper;
    @Autowired
    private RemoteFeeRuleService remoteFeeRuleService;
    @Autowired
    private RemoteH5UserService remoteH5UserService;
    @Autowired
    private OrderBillMapper orderBillMapper;

    //获取未完成订单
    @Override
    public OrderInfo getNoFinishOrder(Long userId) {
        //mp
        return baseMapper.selectOne(new LambdaQueryWrapper<OrderInfo>()
                .eq(OrderInfo::getUserId, userId)
                .in(OrderInfo::getStatus, Arrays.asList("0", "1"))// 订单状态：0:充电中 1：未支付 2：已支付
                .orderByDesc(OrderInfo::getId)
                .last("limit 1")
        );
    }

    //获取订单详细信息
    @Override
    public OrderInfo selectOrderInfoById(Long id) {
        return orderInfoMapper.selectById(id);
    }

    // 创建订单
    @Override
    public Long createOrder(SubmitOrderVo submitOrderVo) {
        //订单对象
        OrderInfo orderInfo = new OrderInfo();

        orderInfo.setUserId(submitOrderVo.getUserId()); //用户id
        orderInfo.setOrderNo(RandomUtil.randomString(8)); //订单编号 随机生成 8位
        orderInfo.setPowerBankNo(submitOrderVo.getPowerBankNo()); //充电宝编号
        orderInfo.setStartTime(new Date()); //订单开始时间
        orderInfo.setStartStationId(submitOrderVo.getStartStationId()); //站点id
        orderInfo.setStartStationName(submitOrderVo.getStartStationName()); //站点名称
        orderInfo.setStartCabinetNo(submitOrderVo.getStartCabinetNo()); //柜机编号

        //远程调用：获取费用规则
        Result<FeeRule> feeRuleResult = remoteFeeRuleService.getFeeRule(submitOrderVo.getFeeRuleId());
        FeeRule feeRule = feeRuleResult.getData();

        orderInfo.setFeeRuleId(submitOrderVo.getFeeRuleId()); //费用规则id
        orderInfo.setFeeRule(feeRule.getDescription()); //费用规则描述
        orderInfo.setStatus("0");  //订单状态
        orderInfo.setCreateTime(new Date()); //创建订单时间
        orderInfo.setCreateBy(SecurityUtils.getUsername()); //订单用户名

        //远程调用获取用户信息
        Result<UserInfo> userInfoResult = remoteH5UserService.getUserInfo(submitOrderVo.getUserId());
        UserInfo userInfo = userInfoResult.getData();

        UserInfoVo userInfoVo = new UserInfoVo();
        BeanUtils.copyProperties(userInfo,userInfoVo);

        orderInfo.setUserInfoVo(userInfoVo);

        orderInfoMapper.insert(orderInfo);
        //返回订单id
        return orderInfo.getId();

    }

    //插入充电宝后结束订单
    @Transactional
    @Override
    public void endOrder(EndOrderVo endOrderVo) {
        //1 根据充电宝编号 + 订单状态（充电中）查询是否存在，如果不存在订单，说明是运营人员插入充电宝，直接返回
        LambdaQueryWrapper<OrderInfo> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(OrderInfo::getPowerBankNo,endOrderVo.getPowerBankNo())
                .eq(OrderInfo::getStatus,"0"); //0：充电中 1：未支付 2：已支付

        OrderInfo orderInfo = orderInfoMapper.selectOne(wrapper);

        if (orderInfo == null){
            return;
        }

        //2 设置订单相关数据，结束订单
        orderInfo.setEndTime(new Date()); //订单结束时间
        orderInfo.setEndStationId(endOrderVo.getEndStationId()); //归还站点id
        orderInfo.setEndStationName(endOrderVo.getEndStationName()); //站点名
        orderInfo.setEndCabinetNo(endOrderVo.getEndCabinetNo()); //柜机编号

        //计算充电时间
        Date startTime = orderInfo.getStartTime(); //开始
        Date endTime = orderInfo.getEndTime(); //结束
        int duration = Minutes.minutesBetween(new DateTime(startTime),new DateTime(endTime)).getMinutes();
        orderInfo.setDuration(duration);

        //TODO 远程调用：规则引擎进行费用计算
        FeeRuleRequestForm feeRuleRequestForm = new FeeRuleRequestForm();
        feeRuleRequestForm.setDuration(duration);
        feeRuleRequestForm.setFeeRuleId(orderInfo.getFeeRuleId());

        Result<FeeRuleResponseVo> feeRuleResponseVoResult = remoteFeeRuleService.calculateOrderFee(feeRuleRequestForm);
        if (Result.FAIL == feeRuleResponseVoResult.getCode()) {
            //远程调用失败
            throw new ServiceException(feeRuleResponseVoResult.getMsg());
        }

        FeeRuleResponseVo feeRuleResponseVo = feeRuleResponseVoResult.getData();

        //设置订单金额
        orderInfo.setTotalAmount(feeRuleResponseVo.getTotalAmount()); //总金额
        orderInfo.setDeductAmount(new BigDecimal(0)); //抵扣金额 暂无优惠
        orderInfo.setRealAmount(feeRuleResponseVo.getTotalAmount()); //实际应支付金额

        //判断是否支付订单 设置状态
        if(orderInfo.getRealAmount().subtract(new BigDecimal(0)).doubleValue() == 0) {
            orderInfo.setStatus("2"); //已支付
        } else {
            orderInfo.setStatus("1"); //未支付
        }

        //插入免费的 订单 前5分钟免费的部分 金额为0
        OrderBill freeOrderBill = new OrderBill();
        freeOrderBill.setOrderId(orderInfo.getId()); //订单id
        freeOrderBill.setBillItem(feeRuleResponseVo.getFreeDescription()); //计费项
        freeOrderBill.setBillAmount(new BigDecimal(0)); //订单金额为0

        //如果有超出免费时长的时间 插入超出免费订单账单 同一订单减去免费的时长 进行计费 计算金额
        if (feeRuleResponseVo.getExceedPrice().doubleValue() > 0){
            OrderBill exceedOrderBill = new OrderBill();
            exceedOrderBill.setOrderId(orderInfo.getId()); //订单id 应与免费数据的订单id相同
            exceedOrderBill.setBillItem(feeRuleResponseVo.getExceedDescription()); // 计费项
            exceedOrderBill.setBillAmount(feeRuleResponseVo.getExceedPrice()); //订单金额 通过规则引擎获得
            orderBillMapper.insert(exceedOrderBill);
        }

    }
}
